package OnlineExam;

import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.sql.*;
import java.io.*;
import java.util.*;
import java.text.*;
import registration.*;
import OnlineExam.question.*;
import OnlineExam.db.*;
import OnlineExam.*;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;

/** 
 *  Evaluates a user's answer paper, the questions which need explanation evaluation are flagged and are then evluated 
 *  by ExplanationEvaluationServlet.
 */


public class EvaluationAction extends Action
{
	//Calculate the grace time.
    private static final int graceTimeMillis = 60*1000;

	/**
	 *  Check if there is a late submission of the answerpaper, returns true iff there is a late submission.
	 */

	private boolean isLateSubmission(long endTimeMillis)
	{

		long currTimeMillis = System.currentTimeMillis();
		
		return (currTimeMillis > (endTimeMillis + graceTimeMillis));
	}
		
    /**
	 *  checks if any explanation fields are present in the request parameters returns true iff they are present. 
	 */
	
    private boolean hasAnyExplanations(HttpServletRequest request, int len)
	{
	    Map m = request.getParameterMap();
		for (int i = 0; i < len; i++)
			if (m.containsKey("Exp" + i))
				return true;

		return false;
	}

	/**
	 *  Action servlet to Evaluate the Answer Paper.
	 */


    public ActionForward execute(ActionMapping mapping,ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws IOException
	{
		
		HttpSession session = request.getSession ();
		long startTimeMillis = (Long) session.getAttribute ("STARTTIMEMILLIS");
		long endTimeMillis = (Long) session.getAttribute("ENDTIMEMILLIS");

		// first check if submission is in time
		if (isLateSubmission(endTimeMillis))
			return (mapping.findForward ("lateSubmission"));
		
		int[] qnumbers = (int []) session.getAttribute ("QNUMBERS");
   		String testId = (String) session.getAttribute ("TESTID");
		
		int maximumMarks = 0;
		int marksScored = 0;
		int totalMarksScored = 0;
		
		try 
		{

			// calcuation of the marks is done here.
			// 
			for (int i = 0; i < qnumbers.length; i++)
			{
				Question q = Question.retrieveQuestion(qnumbers[i]);

				String givenAnswer = request.getParameter ("A"+i+"");
				String explanation = request.getParameter("Exp"+i+"");
				String correctAnswer = "A"+q.getCorrectAnswer();

				if (givenAnswer != null)
				{
					if (givenAnswer.equals (correctAnswer))
					{
						totalMarksScored += q.getCorrectMarks(); 
						marksScored = q.getCorrectMarks();
					}
					else  
					{
						totalMarksScored += q.getWrongMarks();	
						marksScored = q.getWrongMarks();
					}
				}
				else
					marksScored = 0;	
			
				maximumMarks += q.getCorrectMarks();
							
				//stores the test attributes
				QuestionAnswer qa = new QuestionAnswer();
				qa.setTestId(testId);
				qa.setQuestionNumber(qnumbers[i]);
				qa.setAnswer(givenAnswer);
				qa.setMarksScored(marksScored);
				qa.setMaximumMarks(q.getCorrectMarks());
				qa.setExplanation(explanation);
				qa.setEvaluatorsComment(null);
				DBUtil.insert (qa);
			}  // end for			
				
		    // assemble test details
    		User user = (User) session.getAttribute ("USER");
    		Category cat = (Category) session.getAttribute ("CATEGORY");
			
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String dt = sdf.format(System.currentTimeMillis());
						
			Test test = new Test();
			test.setTestId(testId);
			test.setCategoryId(cat.getCategoryId());
			test.setUsername(user.getEmailId());
			test.setDate(dt);
			test.setMarksScored(totalMarksScored); // may be partial if expl. present
			test.setMaximumMarks(maximumMarks);
			test.setStartTime(startTimeMillis);
			test.setEndTime(endTimeMillis);

			if (hasAnyExplanations(request, qnumbers.length))
			{
				test.setEvaluated(0);
				DBUtil.insert (test);
				return (mapping.findForward ("underEvaluation"));
			}
			else
			{
				test.setEvaluated(1);
				DBUtil.insert (test);
				session.setAttribute ("TESTRESULT", test);
				return (mapping.findForward ("result"));
			} // end else
		} //end try
		catch (DBException e) 
		{
			System.out.println ("Exception :"+ e);
			return (mapping.findForward ("dbError"));
		}
	} // end ActionForward
}
